﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LowLevelGraphics.Filter
{
    /// <summary>
    /// A common tone mapping operator.
    /// </summary>
    public abstract class Operator
    {
        /// <summary>
        /// Get Name
        /// </summary>
        public string Name
        {
            get { return this.GetType().Name; }
        }

        public static Operator FromString(string name, string[] tmoParams)
        {
            Operator tmo = null;
            Operators tmoType = Operators.Undefined;

            try
            {
                tmoType = (Operators)Enum.Parse(typeof(Operators), name, true);
            }
            catch
            {
                return null;
            }

            return FromType(tmoType, tmoParams);
        }

        public static Operator FromType(Operators tmoType, string[] tmoParams)
        {

            Operator tmo = FromType(tmoType);

            if (tmo == null)
                return null;

            tmo.SetParams(tmoParams);

            return tmo;
        }

        public static Operator FromType(Operators tmoType)
        {
            Operator tmo = null;

            switch (tmoType)
            {
                case Operators.Biswas:
                    tmo = new Biswas();
                    break;

                case Operators.Drago:
                    tmo = new Drago();
                    break;

                case Operators.Fattal:
                    tmo = new Fattal();
                    break;

                case Operators.Linear:
                    tmo = new Linear();
                    break;

                case Operators.Reinhard05:
                    tmo = new Reinhard05();
                    break;

                case Operators.Schlick:
                    tmo = new Schlick();
                    break;

                case Operators.Stockham:
                    tmo = new Stockham();
                    break;
            }

            return tmo;
        }

        public void Run(float[][,] mapInput, ref float[][,] mapOutput)
        {

            int width = mapInput[0].GetLength(0);
            int height = mapInput[0].GetLength(1);

            mapOutput = new float[3][,];

            for (int i = 0; i < 3; i++)
                mapOutput[i] = new float[width, height];

            Run(mapInput, width, height, ref mapOutput);
        }

        private void SetParams(string[] tmoParams)
        {

            foreach (string param in tmoParams)
            {

                string[] astrParams = param.Split(new char[] { '=' });

                SetParam(astrParams[0], astrParams[1]);
            }
        }

        protected abstract void Run(float[][,] mapInput, int width, int height, ref float[][,] mapOutput);
        protected abstract void SetParam(string param, string value);
    }
}
